package cn.skyisazure.metacompare.sqlcompare.enums;

import cn.skyisazure.metacompare.other.JDBCUtil;
import cn.skyisazure.metacompare.sqlcompare.meta.IndexCM;
import lombok.Getter;

import java.util.Arrays;
import java.util.function.BiPredicate;
import java.util.stream.Collectors;

/**
 * 对每个ddl语句标记类型，此为类型的枚举
 * 每个枚举对应一种验证方法，也可以仅标记此sql类型，如果多个枚举验证方法一样则聚合在一个枚举里使用
 * @author wangjj
 * @date
 */
public enum DdlExecuteTag {
    /* default 不用验证，默认可达 */
    NON((modelBO,executor)->true),
    /* 建库删库语句，仅标记 */
    CREATE_DATASOURCE((modelBO, executor)->true),
    DROP_DATASOURCE((modelBO, executor)->true),
    /*修改、创建索引——验证索引的字段重复数据是否有多条*/
    MODIFY_CREATE_INDEX((modelBO,executor) -> {
        IndexCM indexBO = (IndexCM)modelBO;
        if (!indexBO.getUniqueFlag()) {
            return true;// 非唯一索引不验证
        }
        /*
        String[] columnNames = indexBO.getColumnNames().split(",");
        // 验证重复数据
        String columnNameStr = Arrays.stream(columnNames).map(AnalysisUtil::seal).collect(Collectors.joining(","));
        String columnNameStrNotNull = Arrays.stream(columnNames).map(colNameStr->AnalysisUtil.seal(colNameStr)+" IS NOT NULL").collect(Collectors.joining(" AND "));
        String sql = DDLConstant.formatSql(DDLConstant.DATA_COLUMN_IS_REPEAT_DATA, AnalysisUtil.seal(indexBO.getTableName()),columnNameStrNotNull, columnNameStr);
        if (CollectionUtil.isNotEmpty(executor.queryData(new SqlModel(sql)))) {
            return false;
        }
        // 验证字段长度不能超过3072（通过元数据查询的字段信息）
        String sqlb = "SELECT\n" +
                "\tSUM(c.LEN) as 'len'\n" +
                "FROM\n" +
                "\t`information_schema`.`INNODB_COLUMNS` c\n" +
                "\tLEFT JOIN `information_schema`.`INNODB_TABLES` t ON t.`TABLE_ID` = c.`TABLE_ID`\n" +
                "\tWHERE t.`NAME` = CONCAT(DATABASE(),'/','"+indexBO.getTableName()+"')\n" +
                "\tAND c.`NAME` IN ("+Arrays.stream(columnNames).map(c->AnalysisUtil.seal(c,'\'')).collect(Collectors.joining(","))+")\n" +
                "\tGROUP BY c.`TABLE_ID`";
        Long len = executor.queryValuesOne(new SqlModel(sqlb), Long.class);
        if (len > 3072) {
            return false;
        }*/
        return true;
    }),
    ;

    /** 静态方法：测试是否所有均可达（执行tag里的函数） */
    /*public static Boolean tests(DdlExecuteTag[] ddlExecuteTags,
                                Object modelBO,
                                JDBCUtil.Executor executor){
        return Arrays.stream(ddlExecuteTags)
                .allMatch(ddlExecuteTag -> ddlExecuteTag.getReachable().test(modelBO,executor));
    }*/

    /** 是否可达。参数：BO对象和executor。 true：可达 false：不可达该特殊处理 */
    @Getter
    final BiPredicate<Object, JDBCUtil.Executor> reachable;

    DdlExecuteTag(BiPredicate<Object, JDBCUtil.Executor> reachable) {
        this.reachable = reachable;
    }
}
